package com.kg.alarmclock.service

import android.app.AlarmManager
import android.app.IntentService
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.os.Build
import com.kg.alarmclock.Constant
import com.kg.alarmclock.model.AlarmClockEntity
import com.kg.alarmclock.utils.StringUtils
import java.util.*

class AlarmClockIntentService : IntentService("AlarmClockIntentService") {

    companion object {
        val ENTITY = "entity"

        val TYPE = "type"
        val TYPE_SET = 0
        val TYPE_CANCEL = 1
    }

    private var am: AlarmManager? = null
    private var day_type = Constant.TODAY

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        am = getSystemService(Context.ALARM_SERVICE) as AlarmManager
        return super.onStartCommand(intent, flags, startId)
    }

    override fun onHandleIntent(intent: Intent?) {
        var entity = intent!!.getSerializableExtra(ENTITY) as AlarmClockEntity
        var type = intent!!.getIntExtra(
            TYPE,
            TYPE_SET
        )

        when (type) {
            TYPE_SET -> setAlarm(entity)
            TYPE_CANCEL -> cancelAlarm(entity)
        }
    }

    private fun setAlarm(entity: AlarmClockEntity) {
        var timeMillis =
            StringUtils.dateToStamp("${entity.hour}-${entity.minute}")

        val calendar = Calendar.getInstance()
        val currentHour = calendar.get(Calendar.HOUR_OF_DAY)
        val currentMinute = calendar.get(Calendar.MINUTE)
        if (currentHour < entity.hour || (currentHour == entity.hour && currentMinute < entity.minute)) {
            day_type = Constant.TODAY
        } else {
            day_type = Constant.NEXT
        }

        var dates = entity.dates as ArrayList<Int>
        var date_type = dates[dates.size - 1]

        if (date_type == Constant.NEXT) {
            if (day_type == Constant.NEXT)
                startAlarm(entity, timeMillis + Constant.ONE_DAY)
            else
                startAlarm(entity, timeMillis)
        } else if (date_type == Constant.EVERY) {
            if (day_type == Constant.NEXT)
                startRepeatAlarmDay(entity, timeMillis + Constant.ONE_DAY)
            else
                startRepeatAlarmDay(entity, timeMillis)
        } else
            startRepeatAlarmWeek(entity, timeMillis)

    }

    private fun cancelAlarm(entity: AlarmClockEntity) {
        var dateValues = entity.dateValues

        if (dateValues!!.isNotEmpty()) {
            for (dateValue in dateValues) {
                val intent = Intent(this, AlarmClockReceiver::class.java)
                intent.action = entity.action
                val pendingIntent = PendingIntent.getBroadcast(
                    this,
                    entity.pendingIntentRequestCode + dateValue,
                    intent,
                    0
                )
                am!!.cancel(pendingIntent)
            }
        } else {
            val intent = Intent(this, AlarmClockReceiver::class.java)
            intent.action = entity.action
            val pendingIntent = PendingIntent.getBroadcast(
                this,
                entity.pendingIntentRequestCode,
                intent,
                0
            )
            am!!.cancel(pendingIntent)
        }
    }

    private fun startAlarm(entity: AlarmClockEntity, timeMillis: Long) {
        val intent = Intent(this, AlarmClockReceiver::class.java)
        intent.action = entity.action
        intent.putExtra(AlarmClockReceiver.TIMEMILLIS, timeMillis)
        val pendingIntent = PendingIntent.getBroadcast(
            this,
            entity.pendingIntentRequestCode,
            intent,
            0
        )

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            am!!.setExact(AlarmManager.RTC_WAKEUP, timeMillis, pendingIntent)
        } else
            am!!.set(AlarmManager.RTC_WAKEUP, timeMillis, pendingIntent)
    }

    private fun startRepeatAlarmDay(entity: AlarmClockEntity, timeMillis: Long) {
        val intent = Intent(this, AlarmClockReceiver::class.java)
        intent.action = entity.action
        intent.putExtra(AlarmClockReceiver.TIMEMILLIS, timeMillis)
        val pendingIntent = PendingIntent.getBroadcast(
            this,
            entity.pendingIntentRequestCode,
            intent,
            0
        )

        am!!.setRepeating(AlarmManager.RTC_WAKEUP, timeMillis, Constant.ONE_DAY, pendingIntent)
    }

    private fun startRepeatAlarmWeek(entity: AlarmClockEntity, timeMillis: Long) {
        var dateValues = entity.dateValues

        var timeMillisTotal = 0L
        var dayValueToday = StringUtils.getWeek()

        if (dateValues!!.isNotEmpty()) {
            for (dateValue in dateValues) {
                val intent = Intent(this, AlarmClockReceiver::class.java)
                intent.putExtra(AlarmClockReceiver.TIMEMILLIS, timeMillis)
                intent.action = entity.action
                val pendingIntent = PendingIntent.getBroadcast(
                    this,
                    entity.pendingIntentRequestCode + dateValue,
                    intent,
                    0
                )

                if (dayValueToday < dateValue)
                    timeMillisTotal = timeMillis + (dateValue - dayValueToday) * Constant.ONE_DAY
                else if (dayValueToday == dateValue)
                    if (day_type == Constant.NEXT)
                        timeMillisTotal = timeMillis + Constant.ONE_WEEK
                    else
                        timeMillisTotal = timeMillis
                else
                    timeMillisTotal = (7 + (dateValue - dayValueToday)) * Constant.ONE_DAY

                am!!.setRepeating(
                    AlarmManager.RTC_WAKEUP,
                    timeMillisTotal,
                    Constant.ONE_WEEK,
                    pendingIntent
                )
            }
        }
    }
}